package com.hejia.bulbul.controller;

import com.alibaba.fastjson.JSONObject;
import com.hejia.alauda.entity.*;
import com.hejia.alauda.entity.example.ProductExample;
import com.hejia.alauda.entity.example.TemplateExample;
import com.hejia.alauda.exception.BusinessException;
import com.hejia.alauda.service.*;
import com.hejia.alauda.utils.Pager;
import com.hejia.bulbul.entity.DataTablesReturnObject;
import com.hejia.bulbul.entity.JSONParam;
import com.hejia.bulbul.entity.TemplateFieldModel;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.util.*;

/**
 *
 * Created by Johnny(johnny@hejiajinrong.com) on 14-9-16.
 */

@Controller
@RequestMapping("products")
public class ProductController extends BaseController {
	private final Log logger = LogFactory.getLog(getClass());

	@Resource
	private ProductService productService;

	@Resource
	private StatisticService statisticService;

	@Resource
	private ProductService protocolService;

	@Resource
	private ProductService templateService;

	@Resource
	private ProductService fieldService;

	@Resource
	private ProductService templateValueService;

	@Resource
	private ProductService productTypeService;

	@Resource
	private SaleActivityService saleActivityService;

	@Resource
	private BalanceAndFinancingService financialAssetService;

    @Resource
    private CalendarService calendarService;

	/**
	 * 展示模板列表
	 *
	 * @param pager
	 *            分页信息
	 * @param model
	 *            设置参数的model
	 * @return templates页面
	 */
	@RequestMapping(value = "template/list", method = RequestMethod.GET)
	public String templates(Pager<Template> pager, Model model) {
		templateService.listTemplates(pager);
		model.addAttribute("pager", pager);
		return "/product/template/templates";
	}

	/**
	 * @return 模板添加页面
	 */
	@RequestMapping(value = "template/add", method = RequestMethod.GET)
	public String addTemplate() {
		return "/product/template/add";
	}

	/**
	 * 添加模板动作
	 *
	 * @param fieldModel
	 *            接收List<TemplateField>容器
	 * @param template
	 *            模板
	 * @return 模板展示页面
	 */
	@RequestMapping(value = "template/adding", method = RequestMethod.POST)
	public String addingTemplateAndTemplateField(TemplateFieldModel fieldModel,
			Template template) {
		List<TemplateField> fieldList = fieldModel.getFieldList();

		// 插入template模板记录
		if (templateService.addTemplate(template)) {
			// 插入templateField记录
			for (int i = 0; fieldList != null && i < fieldList.size(); i++) {
				fieldList.get(i).setTemplateId(template.getId());
			}
			if (fieldList != null) {
				fieldService.insertBatch(fieldList);
			}
		}

		return "redirect:list";
	}

	/**
	 * 以ajax格式返回列表请求
	 *
	 * @param params
	 *            回传的参数
	 * @return 返回DataTables期望的数据格式
	 */
	@RequestMapping(value = "templates/ajax", method = RequestMethod.POST)
	@ResponseBody
	public DataTablesReturnObject<Template> tempAsAjax(
			@RequestBody JSONParam[] params) {
		HashMap<String, String> paramMap = JSONParam.convertToMap(params);

		// 分页信息
		Pager<Template> pager = new Pager<>();
		int start = Integer.parseInt(paramMap.get("iDisplayStart"));
		int length = Integer.parseInt(paramMap.get("iDisplayLength"));
		pager.setPageSize(length);
		pager.setPageNumber(start / length + 1);

		// 查询条件
		TemplateExample exp = new TemplateExample();

		String sSearch = paramMap.get("sSearch");
		if (StringUtils.isNotEmpty(sSearch)) {
			exp.appendCriterion("name like  ", "%" + sSearch + "%");
		}
		// 排序
		int iSortingCols = Integer.parseInt(paramMap.get("iSortingCols"));
		for (int i = 0; i < iSortingCols; i++) {
			String iSortCol = paramMap.get("iSortCol_" + i);
			String mDataProp = paramMap.get("mDataProp_" + iSortCol);
			String sSortDir = paramMap.get("sSortDir_" + i);
			if (i > 0) {
				exp.setOrderByClause(exp.getOrderByClause() + ",");
				exp.setOrderByClause(exp.getOrderByClause() + mDataProp + " "
						+ sSortDir);
			} else {
				exp.setOrderByClause(mDataProp + " " + sSortDir);
			}
		}

		pager = templateService.getAllTemplateByCondition(exp, pager);

		return new DataTablesReturnObject<>(pager.getTotalCount(),
				paramMap.get("sEcho"), pager.getList());
	}

	/**
	 * 产品添加或者修改的时候ajax查询productTypeField自定义字段
	 *
	 * @param typeId
	 *            产品分类id
	 * @return ""
	 */
	@RequestMapping(value = "productType/fields", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> getTemplateField(Long typeId) {
		Map<String, Object> map = new HashMap<>();
		// ProductType type = productTypeService.getProductTypeById(typeId);

		List<ProductTypeField> productTypeFields = productTypeService
				.findFieldsByTypeId(typeId);
		map.put("productTypeFields", productTypeFields);

		return map;
	}

	/**
	 * 模板删除
	 *
	 * @param id
	 *            templateId
	 * @param redirectAttributes
	 * @return
	 */
	@RequestMapping(value = "template/delete/{id}", method = RequestMethod.GET)
	public String deleteTemplate(@PathVariable String id,
			RedirectAttributes redirectAttributes) {

		if (templateService.deleteTemplateById(Long.parseLong(id))) {
			redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
			redirectAttributes.addFlashAttribute("msg", "模板删除成功");
		} else {
			redirectAttributes.addFlashAttribute("status", STATUS_FAILD);
			redirectAttributes.addFlashAttribute("msg", "模板无法删除");
		}

		return "redirect:/products/template/list";
	}

	/**
	 * 模板修改页面
	 *
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "template/update/{id}", method = RequestMethod.GET)
	public String updateTemplate(@PathVariable String id, ModelMap model) {
		try {
			Template template = templateService.getTemplateById(Long
					.parseLong(id));
			List<TemplateField> fields = fieldService
					.findTemplateFieldsByTemplateId(Long.parseLong(id));
			model.put("template", template);
			model.put("fields", fields);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e);
		}
		return "/product/template/add";
	}

	// todo
	/**
	 * 模板修改提交
	 *
	 * @param fieldModel
	 * @param template
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "template/updating", method = RequestMethod.POST)
	public String updatingTemplate(TemplateFieldModel fieldModel,
			Template template, Model model) {
		List<TemplateField> fieldList = fieldModel.getFieldList();
		List<TemplateField> fields = new ArrayList<>();
		// 插入template模板记录
		if (templateService.updateTemplate(template)) {
			// 插入templateField记录
			for (int i = 0; fieldList != null && i < fieldList.size(); i++) {
				if (fieldList.get(i).getName() != null) {
					fieldList.get(i).setTemplateId(template.getId());
					fields.add(fieldList.get(i));
				}
			}
			fieldService.deleteByTemplateId(template.getId());
			fieldService.insertBatch(fields);
		}

		return "/product/template/templates";
	}

	/**
	 * 产品添加页面
	 *
	 * @param model
	 *            model
	 * @return 产品添加页面
	 */
	@RequestMapping(value = "add", method = RequestMethod.GET)
	public String showAddProduct(ModelMap model) {

		// 获取产品分类列表
		List<ProductType> ptList = productTypeService.listProductType(null)
				.getList();
		// 获取活动
		List<SaleActivity> saList = saleActivityService.effectiveActivity();
		// 获取金融资产库存
		List<FinancialAsset> financialAssets = financialAssetService
				.findFinancialAssetInventory();

		model.put("productTypeList", ptList);
		model.put("saleActivityList", saList);
		model.put("financialAssets", financialAssets);

		return "/product/input";
	}

	/**
	 * 判断结息日是否节假日
	 * 
	 * @param valueDate 起息日
	 * @param endTime 截止销售时间
	 * @param term 天数
	 * @return 1 - 是节假日，0 - 不是节假日
	 */
	@RequestMapping(value = "isHoliday", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> isHoliday(String valueDate, String endTime, int term) {
		Map<String, Object> result = new HashMap<String, Object>();
		if ((StringUtils.isNotEmpty(valueDate) && calendarService.isHoliday(valueDate, term))
		|| (StringUtils.isNotEmpty(endTime) && calendarService.isHoliday(endTime, term))) {
			result.put("status", "1");
			return result;
		}
		result.put("status", "0");
		return result;
	}

	/**
	 * 产品添加动作
	 *
	 * @param product
	 * @param protocolIds
	 * @param model
	 * @param redirectAttributes
	 * @return
	 */
	@RequestMapping(value = "add", method = RequestMethod.POST)
	public String addProduct(String productTypeFields, Long typeId,
			Product product,
			@RequestParam(value = "protocolIds") Long[] protocolIds,
			ModelMap model, RedirectAttributes redirectAttributes) {
		try {
			// 转换产品收益规则利率
			convertProductEarningsRuleInterestRate(product);
						
			ProductType pt = productTypeService.getProductTypeById(typeId);
			product.setType(pt);
			
			this.productService.checkInventory(product);
			if (productService.saveProduct(product)) {
				for (Long id : protocolIds) {
					if (id == null) {
						continue;
					}

					Protocol protocol = this.protocolService
							.findProtocolById(id);
					protocol.setProductId(product.getId());
					protocol.setModifyDate(new Date());
					protocolService.modifyProtocol(protocol);
				}

				/*
				 * 添加模版自定义字段值
				 */
				if (pt != null) {
					updateProductTypeValue(product.getId(), typeId,
							productTypeFields);
				}

				redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
				redirectAttributes.addFlashAttribute("msg", "产品添加成功");
			} else {
				redirectAttributes.addFlashAttribute("status", STATUS_FAILD);
				redirectAttributes.addFlashAttribute("msg", "产品添加失败");
			}
		} catch (Exception e) {
			logger.error("添加产品失败", e);
			redirectAttributes.addFlashAttribute("status", STATUS_FAILD);
			redirectAttributes.addFlashAttribute("msg", "产品添加失败 " + e.getMessage());
		}

		return "redirect:/products/list";
	}

	/**
	 * 产品删除
	 *
	 * @param serial
	 * @param redirectAttributes
	 * @return
	 */
	@RequestMapping(value = "delete/{serial}", method = RequestMethod.GET)
	public String deleteProduct(@PathVariable String serial,
			RedirectAttributes redirectAttributes) {

		try {
			if (productService.deleteProduct(serial)) {
				redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
				redirectAttributes.addFlashAttribute("msg", "产品删除成功");
			} else {
				redirectAttributes.addFlashAttribute("status", STATUS_FAILD);
				redirectAttributes.addFlashAttribute("msg", "已上架产品或已下订单无法删除");
			}
		} catch (Exception e) {
			logger.error("删除产品失败", e);
			redirectAttributes.addFlashAttribute("status", STATUS_FAILD);
			redirectAttributes.addFlashAttribute("msg",
					"删除产品失败 " + e.getMessage());
		}

		return "redirect:/products/list";
	}

	/**
	 * 产品修改页面
	 *
	 * @param serial
	 *            产品序列
	 * @param model
	 *            model
	 * @return 产品修改页面
	 */
	@RequestMapping(value = "update/{serial}", method = RequestMethod.GET)
	public String showUpdateProduct(@PathVariable String serial, ModelMap model) {
		Product product = productService.getProductBySerial(serial);
		List<Protocol> protocol = protocolService
				.getProtocolsByProductId(product.getId());

		if (product.getType() != null) {
			setProductTypeValue2Model(product.getId(), product.getType()
					.getId(), "productTypeValue", model);
		}

		// 获取产品分类列表
		List<ProductType> ptList = productTypeService.listProductType(null)
				.getList();
		model.put("productTypeList", ptList);

		// 获取活动
		List<SaleActivity> saList = saleActivityService.effectiveActivity();
		model.put("saleActivityList", saList);

		model.put("protocol", protocol);
		model.put("product", product);

		return "/product/input";
	}

	/**
	 * 设置值productTypeValue
	 */
	private void setProductTypeValue2Model(Long productId, Long typeId,
			String productTypeValue, ModelMap model) {
		if (typeId == null) {
			return;
		}

		Map<String, String> fieldValues = new HashMap<>();

		/*
		 * 类型表对应的所有字段
		 */
		List<ProductTypeField> fields = productTypeService
				.findFieldsByTypeId(typeId);
		/*
		 * 对应的值，json格式
		 */
		ProductTypeValue typeValue = productTypeService
				.findProductTypeValueByProductId(productId);
		if (typeValue != null) {
			JSONObject jsonObject = JSONObject
					.parseObject(typeValue.getValue());
			for (int i = 0; fields != null && i < fields.size(); i++) {
				String key = fields.get(i).getCode();
				String value = (String) jsonObject.get(key);

				fieldValues.put(key, value);
			}
		}

		model.put("productTypeFieldValue", fieldValues);
		model.put("productTypeFields", fields);
	}

	/**
	 * 产品修改提交
	 *
	 * @param product
	 *            产品
	 * @param protocolIds
	 *            ...
	 * @param serial
	 *            产品序列
	 * @param model
	 *            model
	 * @param redirectAttributes
	 *            重定向字段存储
	 * @return 产品列表
	 */
	@RequestMapping(value = "update/{serial}", method = RequestMethod.POST)
	public String updateProduct(String productTypeFields, Long typeId,
			Product product,
			@RequestParam(value = "protocolIds") Long[] protocolIds,
			@PathVariable String serial, ModelMap model,
			RedirectAttributes redirectAttributes) {
		
		ProductExample example = new ProductExample();
		example.appendCriterion("serial=", serial);
		Long productId = productService.getProductBySerial(serial).getId();

		ProductType pt = productTypeService.getProductTypeById(typeId);
		product.setType(pt);

		try {
			
			// 转换产品收益规则利率
			convertProductEarningsRuleInterestRate(product);			
			if (productService.updateProduct(product, serial)) {
				for (Long id : protocolIds) {
					if (id == null) {
						continue;
					}
					Protocol protocol = this.protocolService
							.findProtocolById(id);
					protocol.setProductId(productId);
					protocol.setModifyDate(new Date());
					protocolService.modifyProtocol(protocol);
				}
				/*
				 * 更新自定义字段值
				 */
				if (pt != null) {
					updateProductTypeValue(productId, typeId, productTypeFields);
				}

				redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
				redirectAttributes.addFlashAttribute("msg", "产品修改成功");
			} else {
				redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
				redirectAttributes.addFlashAttribute("msg", "产品修改失败");
			}
		} catch (BusinessException e) {
			redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
			redirectAttributes.addFlashAttribute("msg",
					"产品修改失败 " + e.getMessage());
		} catch (Exception e) {
			redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
			redirectAttributes.addFlashAttribute("msg", "产品修改失败 ");
		}

		return "redirect:/products/list";
	}

	/**
	 * 转换产品收益规则利率
	 * @param product
	 */
	private void convertProductEarningsRuleInterestRate(Product product) {
		if(product.getEarningsRules() == null){
			return;
		}
		for(ProductEarningsRule rule : product.getEarningsRules()){
			rule.setInterestRate(rule.getInterestRate().divide(BigDecimal.valueOf(100)));
		}
	}

	/**
	 * 添加或修改 产品类型自定义字段值
	 *
	 * @param productId
	 *            产品id
	 * @param typeId
	 *            产品类型id
	 * @param productTypeFields
	 *            自定义字段json串
	 * @throws BusinessException
	 */
	private void updateProductTypeValue(Long productId, Long typeId,
			String productTypeFields) throws BusinessException {
		if (productId == null || typeId == null) {
			return;
		}
		/*
		 * 承兑银行特殊处理
		 */
		Product product = productService.getProductById(productId);
		JSONObject json = JSONObject.parseObject(productTypeFields);
		if (json.containsKey("acceptingBank")) {
			product.setAcceptingBank(json.getString("acceptingBank"));
			productService.updateProduct(product, product.getSerial());
		}

		ProductTypeValue ptv = productTypeService
				.findProductTypeValueByProductId(productId);
		if (ptv != null && "{}".equals(productTypeFields)) {
			productTypeService.deleteProductTypeValue(ptv);
			return;
		}
		if (ptv == null && StringUtils.isNoneBlank(productTypeFields)) {
			ptv = new ProductTypeValue();
			ptv.setProductId(productId.toString());
			ptv.setTypeId(typeId);
			ptv.setValue(productTypeFields);
			productTypeService.insertProductTypeValue(ptv);
		} else if (ptv != null) {
			ptv.setValue(productTypeFields);
			ptv.setTypeId(typeId);
			productTypeService.updateProductTypeValue(ptv);
		}
	}

	@RequestMapping(value = "publish/{serial}", method = RequestMethod.GET)
	public String publishProduct(@PathVariable String serial,
			RedirectAttributes redirectAttributes) {
		if (productService.publishProduct(serial)) {
			redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
			redirectAttributes.addFlashAttribute("msg", "产品上架成功");
		} else {
			redirectAttributes.addFlashAttribute("status", STATUS_FAILD);
			redirectAttributes.addFlashAttribute("msg", "产品下架成功");
		}

		return "redirect:/products/list";

	}
	
	@RequestMapping(value = "timepublish/{serial}", method = RequestMethod.GET)
	public String timePublishProduct(@PathVariable String serial,
			RedirectAttributes redirectAttributes) {
		if (productService.timePublishProduct(serial)) {
			redirectAttributes.addFlashAttribute("status", STATUS_SUCCESS);
			redirectAttributes.addFlashAttribute("msg", "产品到点上架成功");
		} else {
			redirectAttributes.addFlashAttribute("status", STATUS_FAILD);
			redirectAttributes.addFlashAttribute("msg", "产品到点上架失败");
		}

		return "redirect:/products/list";

	}

	@RequestMapping("list")
	public String listProduct(Pager<Product> pager, ModelMap model) {

		Pager<Product> products = productService.getAllProducts(pager);
		model.put("products", products);

		return "product/list";
	}

	
	@RequestMapping(value = "saleNotify", method = RequestMethod.GET)
	public String sendSaleNotify(ModelMap model) {
		int count = productService.countSaleNotify();
		model.put("count", count);
		return "product/saleNotify";
	}
	
	
	@RequestMapping(value = "saleNotify", method = RequestMethod.POST)
	public String sendSaleNotify(String content, ModelMap model) {
		
		if(StringUtils.isNotBlank(content)){
			productService.sendSaleNotify(content);
			model.put("success", 1);
		}else
			model.put("success", 0);
		
		
		return "product/saleNotify";
	}
	
	
	/**
	 * 以ajax格式返回列表请求
	 *
	 * @param params
	 * @return
	 */

	@RequestMapping(value = "list/ajax", method = RequestMethod.POST)
	@ResponseBody
	public DataTablesReturnObject<Product> listAsAjax(
			@RequestBody JSONParam[] params) {
		HashMap<String, String> paramMap = JSONParam.convertToMap(params);

		// 分页信息
		Pager<Product> pager = new Pager<Product>();
		int start = Integer.parseInt(paramMap.get("iDisplayStart"));
		int length = Integer.parseInt(paramMap.get("iDisplayLength"));
		pager.setPageSize(length);
		pager.setPageNumber(start / length + 1);

		// 查询条件
		ProductExample exp = new ProductExample();

		String sSearch = paramMap.get("sSearch");
		if (StringUtils.isNotEmpty(sSearch)) {
			exp.appendCriterion("name like  ", "%" + sSearch + "%");
		}
		// 排序
		int iSortingCols = Integer.parseInt(paramMap.get("iSortingCols"));
		for (int i = 0; i < iSortingCols; i++) {
			String iSortCol = paramMap.get("iSortCol_" + i);
			String mDataProp = paramMap.get("mDataProp_" + iSortCol);
			String sSortDir = paramMap.get("sSortDir_" + i);
			if (i > 0) {
				exp.setOrderByClause(exp.getOrderByClause() + ",");
				exp.setOrderByClause(exp.getOrderByClause() + mDataProp + " "
						+ sSortDir);
			} else {
				exp.setOrderByClause(mDataProp + " " + sSortDir);
			}
		}

		pager = productService.getAllProducts(exp, pager);

		DataTablesReturnObject<Product> dtr = new DataTablesReturnObject<Product>(
				pager.getTotalCount(), paramMap.get("sEcho"), pager.getList());
		return dtr;
	}

}
